package yagwl.client.view.demo;

import yagwl.client.model.ItemDTO;
import yagwl.client.model.TreeNodeDTO;
import yagwl.client.model.demo.ProductCategoryTreeCache;
import yagwl.client.model.demo.ProductListCache;
import yagwl.client.widget.FormFieldGroup;
import yagwl.client.widget.FormPanel;
import yagwl.client.widget.FormPanel.SaveButtonClickCallback;
import yagwl.client.widget.ManagedTree;
import yagwl.client.widget.Section;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class ProductHierarchy extends Composite {

  public static final String HistoryToken = "productTree";
  private ManagedTree tree = new ManagedTree();
  private ProductCategoryTreeCache treeCache = new ProductCategoryTreeCache();

  public ProductHierarchy(ProductListCache listCache) {
    Section rootSection = new Section("Product Catalog");
    rootSection.setDescription(new HTML(desc));
    rootSection.setFootnote(new HTML(footNote));
    Button productsB = new Button("Manage Products");
    VerticalPanel vp = new VerticalPanel();
    // vp.add(new Spacer(1, 5));
    vp.add(productsB);
    // vp.add(new Spacer(1, 10));
    vp.add(tree);
    vp.setWidth("100%");
    vp.setCellHorizontalAlignment(productsB, HasHorizontalAlignment.ALIGN_RIGHT);
    rootSection.setContent(vp);
    initWidget(rootSection);

    tree.enableCreateTreeNode("Create category");
    tree.enableDeleteTreeNode("Delete category and all its sub-categories");
    tree.enableUpdateTreeNodeLabel("Edit category name");
    tree.enableUpdateTreeNode("Update category", new CategoryDetailDialogBox());
    tree.enableAddTreeNodeItem("Add product to category",
        new SelectProductDialogBox(listCache));
    tree.enableRemoveTreeNodeItem("Remove product from category");
    tree.setTreeNodeLabel("Category");
    tree.setTreeCache(treeCache);
    initCellTableColumns();
    tree.renderUI();

    productsB.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        History.newItem(ProductListView.HistoryToken, true);
      }
    });
  }

  private void initCellTableColumns() {
    TextColumn<ItemDTO> nameColumn = new TextColumn<ItemDTO>() {
      @Override
      public String getValue(ItemDTO item) {
        return item.get("name");
      }
    };
    tree.addTableColumn(nameColumn, "Name");
    TextColumn<ItemDTO> descColumn = new TextColumn<ItemDTO>() {
      @Override
      public String getValue(ItemDTO item) {
        return item.get("description");
      }
    };
    tree.addTableColumn(descColumn, "Description");
  }

  private class CategoryDetailDialogBox extends
      ManagedTree.AbstractTreeNodeUpdateDialogBox {

    private Label nameL = new Label();
    private TextBox imgTB = new TextBox();
    private FormPanel rootFP = new FormPanel();

    public CategoryDetailDialogBox() {
      tree.super();
      setText("Category Detail");
      setAnimationEnabled(true);
      imgTB.setWidth("400px");
      FormFieldGroup ffg = new FormFieldGroup();
      ffg.addField("Name", nameL);
      ffg.addField("Image URL", imgTB);
      rootFP.addFieldGroup(ffg);
      rootFP.addSaveButton("Update", new SaveButtonClickCallback() {

        @Override
        public void save() {
          TreeNodeDTO updatedNode = new TreeNodeDTO();
          updatedNode.put("name", nameL.getText());
          updatedNode.put("imageUrl", imgTB.getText());
          treeCache.updateNode(getTreeNodeDTO(), updatedNode);
        }
      });

      rootFP.addCloseDialogBoxButton("Cancel", this);
      rootFP.renderUI();
      setWidget(rootFP);
    }

    @Override
    public void populate() {
      TreeNodeDTO catOrig = (TreeNodeDTO) getTreeNodeDTO();
      nameL.setText((String) catOrig.get("name"));
      imgTB.setText((String) catOrig.get("imageUrl"));
    }

    @Override
    public void setSuccessMessage() {
      rootFP.setMessage("Updated!");
    }

    @Override
    public void setErrorMessage(String errorMessage) {
      rootFP.setErrorMessage(errorMessage);
    }
  }

  private static final String desc = "ManagedTree builds on GWT Tree and GWT CellTable "
      + "to provide tree management capabilities. Listens to a custom event, ItemListEvent, to "
      + "populate the entire tree. Lazy loading is a future enhancement candidate. "
      + "Listens to another custom event, TreeNodeEvent, to handle tree operations.";

  private static final String footNote = "<br>Data is backed by App Engine Datastore, "
      + "however, only transactions of authorized users are committed.";
}
